package com.android.systemui.ios.views;

import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;

import com.android.systemui.ios.Constants;
import com.android.systemui.ios.IActionEventCallback;
import com.android.systemui.ios.IGuardService;
import com.android.systemui.ios.IStatusBarCallback;
import com.android.systemui.ios.R;
import com.android.systemui.ios.wall.PageWallpaperView;

import java.util.concurrent.atomic.AtomicInteger;

public class ShadeBarWindowView extends FrameLayout {

    private final boolean DEBUG = false;
    private final String TAG = "wss";

    private View mShadeMainView;
    private PageDateTimeView mDateTimeView;
    private PageShortcutView mShortcutView;
    private PageWallpaperView mWallView;
    private VelocityTracker mVelocityTracker;
    private IGuardService mService;
    private IActionEventCallback mEventCallback;
    private final AtomicInteger mKeyguardTimeout = new AtomicInteger(0);

    private int mDeltaX;
    private int mDeltaY;
    private float mLastMotionX;
    private float mLastMotionY;
    private int mInUnlockMode = -1;
    private boolean isNeedPassword = false;
    private boolean isPrepareShortcut = false;

    private final int MODE_KEYGUARD = -3;
    private final int MODE_IGNORE = -2;
    private final int MODE_INTERCEPT = -1;
    private final int MODE_NONE = 0;
    private final int MODE_UNLOCK = 2;
    private final int MODE_SHORTCUT = 3;

    public ShadeBarWindowView(Context context) {
        this(context, null, 0);
    }

    public ShadeBarWindowView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ShadeBarWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        mShadeMainView = findViewById(R.id.shade_window_view);
        mDateTimeView = findViewById(R.id.page_date_time_view);
        mShortcutView = findViewById(R.id.page_shortcut_layout);
        mWallView = findViewById(R.id.page_wallpaper_main);

        mDateTimeView.setPageShortcutView(mShortcutView);
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        WindowManager wm = getContext().getSystemService(WindowManager.class);
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getRealMetrics(metrics);
        Constants.screenWidth = metrics.widthPixels;
        Constants.screenHeight = metrics.heightPixels;
        Constants.screenDensity = metrics.density;
        mDateTimeView.updateLocation(false);
    }

    public IStatusBarCallback getDateTimeView() {
        return mDateTimeView;
    }

    public IStatusBarCallback getShortcutIcons() {
        return mShortcutView.getShortcutIcons();
    }

    public void setActionEventCallback(IGuardService service, IActionEventCallback callback) {
        mService = service;
        mEventCallback = callback;
        if (mDateTimeView != null) {
            mDateTimeView.setActionEventCallback(service, callback);
        }
        if (mShortcutView != null) {
            mShortcutView.setActionEventCallback(service, callback);
        }
        if (mWallView != null) {
            mWallView.setActionEventCallback(service, callback);
        }
    }

    public void setLockIconLocked(boolean lock) {
        if (mDateTimeView != null) {
            mDateTimeView.setLockIconLocked(lock);
        }
    }

    public void setShowLockIcon(boolean show) {
        if (mDateTimeView != null) {
            mDateTimeView.setShowLockIcon(show);
        }
    }

    public void setFacePreviewEnable(boolean en) {
        if (Constants.KEYGUARD_ENABLE && mDateTimeView != null) {
            mDateTimeView.setFacePreviewEnable(en);
        }
    }

    public boolean checkPassword() {
        if (mService != null) {
            if (mService.isLocked()) {
                if (mDateTimeView != null) {
                    mDateTimeView.setPasswordVisible(true);
                    return false;
                }
            }
        }
        return true;
    }

    public void resetKeyguard() {
        mShadeMainView.setY(0);
        if (mWallView != null) {
            mWallView.exitScreen();
        }
        if (mDateTimeView != null) {
            mDateTimeView.resetCenter();
        }
        if (mShortcutView != null) {
            mShortcutView.setAlpha(0.0f);
            mShortcutView.setVisibility(GONE);
        }
    }

    public void updateLocation(int y) {
        if (isPrepareShortcut) {
            float alpha = Math.min((Constants.screenHeight + y) * 1.0f / Constants.slideTopBarHeight, 1.0f);
            mShortcutView.setAlpha(alpha);
        } else {
            mShadeMainView.setY(y);
        }
    }

    public void smoothExpand() {
        Constants.isExpanded = true;
        isPrepareShortcut = false;
        mShadeMainView.animate().translationY(0).start();
    }

    public void smoothCollapse() {
        Constants.isExpanded = false;
        isPrepareShortcut = false;
        mShadeMainView.animate().translationY(-Constants.screenHeight).setDuration(220).withEndAction(new Runnable() {

            @Override
            public void run() {
                mShortcutView.setVisibility(GONE);
                if (mWallView != null) {
                    mWallView.exitScreen();
                }
                if (mEventCallback != null) {
                    mEventCallback.onCollapse();
                }
            }
        }).start();
    }

    public void showWallpaperSelect() {
        mWallView.entryScreen();
    }

    public void showShortcut() {
        mShortcutView.animate().alpha(1.0f).start();
    }

    public void hideShortcut() {
        Constants.isExpanded = false;
        isPrepareShortcut = false;
        if (mDateTimeView.isShown()) {
            mShortcutView.animate().alpha(0.0f).withEndAction(new Runnable() {

                @Override
                public void run() {
                    mShortcutView.setVisibility(GONE);
                }
            }).start();
        } else {
            mShortcutView.animate().alpha(0.0f).withEndAction(new Runnable() {

                @Override
                public void run() {
                    mShadeMainView.setY(-Constants.screenHeight);
                    mDateTimeView.setVisibility(VISIBLE);
                    mShortcutView.setVisibility(GONE);
                    if (mWallView != null) {
                        mWallView.exitScreen();
                    }
                    if (mEventCallback != null) {
                        mEventCallback.onCollapse();
                    }
                }
            }).start();
        }
    }

    public void startFromTopShortcut() {
        isPrepareShortcut = true;
        mShortcutView.setAlpha(0.0f);
        mShortcutView.setVisibility(VISIBLE);
        mShortcutView.postRefresh();
        mDateTimeView.setVisibility(GONE);
        mShadeMainView.setY(0);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mKeyguardTimeout.set(Integer.MAX_VALUE);
                break;
            case MotionEvent.ACTION_UP:
                mKeyguardTimeout.set(15);
                break;
        }
        return super.dispatchTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getAction();
        final float x = event.getX();
        final float y = event.getY();
        if (Constants.isInWallpaper) {
            return super.onTouchEvent(event);
        }
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(event);
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mLastMotionX = x;
                mLastMotionY = y;
                if (Constants.KEYGUARD_ENABLE && !Constants.isExpanded) {
                    mInUnlockMode = MODE_KEYGUARD;
                } else {
                    if (y > Constants.screenHeight - Constants.unlockBottomHeight) {
                        mInUnlockMode = MODE_INTERCEPT;
                        if (mService != null) {
                            isNeedPassword = mService.isLocked();
                        }
                        if (mDateTimeView != null && mDateTimeView.isFaceDiscernSuccess()) {
                            if (mService != null) {
                                mService.requestLock(0);
                            }
                            isNeedPassword = false;
                        }
                    } else if (y < Constants.slideTopBarHeight && x > Constants.screenWidth / 2.0f) {
                        mInUnlockMode = MODE_INTERCEPT;
                        mShortcutView.setAlpha(0.0f);
                        mShortcutView.setVisibility(VISIBLE);
                        mShortcutView.postRefresh();
                    } else {
                        mInUnlockMode = MODE_IGNORE;
                    }
                }
                if (DEBUG)
                    Log.i(TAG, "shade bar touch down, mInUnlockMode=" + mInUnlockMode + ", y = " + y);
                break;

            case MotionEvent.ACTION_MOVE:
                mDeltaX = (int) (mLastMotionX - x);
                mDeltaY = (int) (mLastMotionY - y);
                if (mInUnlockMode == MODE_INTERCEPT) {
                    if (Math.abs(mDeltaX) < Math.abs(mDeltaY)) {
                        if (mLastMotionY < Constants.slideTopBarHeight) {
                            mInUnlockMode = MODE_SHORTCUT;
                        } else {
                            mInUnlockMode = MODE_UNLOCK;
                        }
                    } else if (Math.abs(mDeltaX) > Math.abs(mDeltaY)) {
                        mInUnlockMode = MODE_NONE;
                    }
                }

                if (mInUnlockMode == MODE_UNLOCK) {
                    if (isNeedPassword) {
                        mDateTimeView.updatePasswordLayout(mDeltaY);
                    } else {
                        if (mDeltaY >= 0) {
                            mShadeMainView.setY(-mDeltaY);
                        } else {
                            mShadeMainView.setY(0);
                        }
                    }
                } else if (mInUnlockMode == MODE_SHORTCUT) {
                    float alpha = Math.min(-mDeltaY * 1.5f / Constants.pageTurningSize, 1.0f);
                    mShortcutView.setAlpha(alpha);
                }
                if (DEBUG)
                    Log.i(TAG, "shade bar touch move, deltaX =" + mDeltaX + ", deltaY=" + mDeltaY);
                break;

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                mVelocityTracker.computeCurrentVelocity(500);
                float velocityY = mVelocityTracker.getYVelocity();
                if (DEBUG)
                    Log.i(TAG, "shade bar touch up, velocityY=" + velocityY + ", mDeltaY=" + mDeltaY);
                if (mInUnlockMode == MODE_UNLOCK) {
                    if (isNeedPassword) {
                        mDateTimeView.setPasswordVisible(velocityY < -Constants.pageTurningVelocity || mDeltaY > Constants.pageTurningSize);
                    } else {
                        if (velocityY < -Constants.pageTurningVelocity || mDeltaY > Constants.pageTurningSize) {
                            if (DEBUG) Log.i(TAG, "shade bar touch up, Unlock success.");
                            smoothCollapse();
                        } else {
                            smoothExpand();
                        }
                    }
                } else if (mInUnlockMode == MODE_SHORTCUT) {
                    if (velocityY > Constants.pageTurningVelocity / 2.0f || mDeltaY < -Constants.pageTurningSize / 2) {
                        mShortcutView.animate().alpha(1.0f).start();
                    } else {
                        mShortcutView.animate().alpha(0.0f).withEndAction(new Runnable() {

                            @Override
                            public void run() {
                                mShortcutView.setVisibility(GONE);
                            }
                        }).start();
                    }
                } else if (mInUnlockMode == MODE_KEYGUARD) {
                    if (velocityY < -Constants.pageTurningVelocity || mDeltaY > Constants.pageTurningSize / 2) {
                        if (mEventCallback != null) {
                            mEventCallback.onResetKeyguard();
                        }
                        if (mService != null) {
                            mService.sendKeyEvent(KeyEvent.KEYCODE_HOME, 0);
                        }
                    }
                }
                break;
        }

        if (mInUnlockMode == MODE_IGNORE) {
            return super.onTouchEvent(event);
        }
        return true;
    }
}
